<template>
  <div>
    <!-- 1.头部导航栏的设置 -->
    <van-nav-bar fixed>
      <template #left>
        <img :src="imgPng" alt="" class="imgSize" />
      </template>
      <template #right>
        <van-icon name="search" size="18" color="#fff" @click="skipFn" />
      </template>
    </van-nav-bar>
    <!-- 1.2.频道部分--active在首页对应位置使用, animated切换动画设置
    定位的头部导航挡住, 给tabs设置固定定位/粘性定位sticky, 距离上边 offset-top：46px(手动转rem)
    粘性定位：正常随着页面滚动, 到达指定位置, 变成固定定位
    列表的头部和内容都是默认置顶的如果有固定的头部导航栏固定定位的话
     列表的头部和内容都需要加一个padding-top-->
    <!-- 1.4* 在van-tabs上修改v-model变量名(把active换成channelId)
     * 在van-tab绑定name属性和值(值为频道ID)
     * 点van-tab后,name值会自动绑定给v-model(vant组件内部实现的) -->
    <!-- 因为每一次点击切换其他频道需要通过id重新去渲染页面 -->
    <van-tabs v-model="channelId" animated sticky :before-change="tabsBeforeChangeFn"  @change="tabsChangeFn" offset-top="1.226667rem">
      <van-tab
        :title="list.name"
        v-for="list in channelsList"
        :key="list.id"
        :name="list.id"

      >
        <!-- 1.3.封装一个组件存放频道列表的内容r't'y'h'mrtyhm -->
        <ArticleList :cid="channelId"></ArticleList>
      </van-tab>
    </van-tabs>
    <!--1.5 编辑频道图标
    点击+出现一个遮罩层 遮罩层里面包裹着内容 -->
    <van-icon
      name="plus"
      size="0.37333334rem"
      class="moreChannels"
      @click="show = true"
    />
    <!-- 弹出层组件 绑定一个v-model show为fasle隐藏否则显示
    1.8@closed='closedFn'是弹出层自定义的事件关闭弹出层触发改方法 -->
    <van-popup v-model="show" class="edit_wrap" @closed="closedFn">
      <!-- 弹出层的主体区域 -->
      <ChannelEdit
        @close="show = false"
        :userChannelList="channelsList"
        @addChannel="addChannelFn"
        @removeChannel="removeChannelFn"
        @changeChannel="channgeChannelFn"
        ref="channelEdit"
      ></ChannelEdit>
    </van-popup>
  </div>
</template>

<script>
import { userChannelListAPI, updataChannelListAPI } from '../../api'
import logoPng from '../../assets/toutiao_logo.png'
import ArticleList from './components/ArticleList.vue'
import ChannelEdit from './components/ChannelEdit.vue'
// 2.优化切换导航栏保存对应的滚动条高度
// “频道名称”和“滚动条位置”之间的对应关系，
// 格式 { '推荐ID': 211, 'htmlID': 30, '开发者资讯ID': 890 }
const nameToTop = {}// {0：978,1:100}
export default {
  data () {
    return {
      imgPng: logoPng,
      channelId: 0,
      channelsList: [],
      show: false // 控制遮罩层显示
    }
  },
  // 1.3拿到频道列表接口数据,渲染页面
  async created () {
    const res = await userChannelListAPI()
    this.channelsList = res.data.data.channels
  },
  components: {
    ArticleList,
    ChannelEdit
  },
  methods: {
    // 1.6和1.7添加和删除都是需要公用一个接口封装一下
    async updataChannelLis () {
      // 需要把添加的数据传递给后端接口实现动态绑定
      // 接口参数格式 channels[{id:1,sel:1}]
      // 1.需要去掉推荐频道id为0
      // 2.需要将sel添加到每一个对象中 sel是当前的顺序 index+1
      // 3.传入到后端的参数不需要name 需要delete删除
      // 4调用接口的时候需要在外层包一个channels
      const list = this.channelsList.filter((item) => {
        return item.id !== 0
      })
      const newArr = list.map((item, index) => {
        const newObj = { ...item } // 浅拷贝(让对象和原数组脱离关系)
        newObj.sel = index + 1
        delete newObj.name
        return newObj // map会收集每次遍历return的值形成一个新数组
      })
      await updataChannelListAPI({
        channels: newArr
      })
    },
    // 1.6添加操作
    addChannelFn (item) {
      // 点击更多频道对应项添加到频道list:子传父
      this.channelsList.push(item)
      this.updataChannelLis()
    },
    // 1.7 删除操作
    // 通过点击找到对应的id然后通过数组去找到对应的索引
    // 通过索引删除这一项
    removeChannelFn (item) {
      const index = this.channelsList.findIndex((obj) => obj.id === item.id)
      this.channelsList.splice(index, 1)
      this.updataChannelLis()
    },
    // 1.8关闭弹出层需要重置我的频道的编辑和完成状态
    // 可以通过refs拿到整个组件的实列
    // 可以通过ref和$refs来获取子组件对象, 然后操作子组件对象里的一切
    closedFn () {
      this.$refs.channelEdit.isEdit = false
    },
    // 1.9拿到对应的item找到点击对应id赋值给channelId
    // channelId是v-model只要值改变会自动的调用接口找到对应的频道列表内
    // 切换频道
    channgeChannelFn (item) {
      this.channelId = item.id // 传过来的频道ID, 影响tabs默认v-model的选择
    },
    skipFn () {
      this.$router.push('/search')
    },
    // 2.2.给nameToTop赋值
    // 这个方法参考vant,主要把对应的频道页面的高度缓存起来-切换其他频道才缓存
    // 该方法必须返回true否则保留在原地不缓存
    tabsBeforeChangeFn () {
      nameToTop[this.channelId] = window.scrollY
      console.log(nameToTop)
      return true
    },
    // 2.3如果频道发生改变把对应的频道id的高度赋值
    // 来回切换tabs的时候滚动条的重新定位-首先需要捕获到tabs切换事件
    // 找得到对应id所对应 的滚动条事件-使用scrollTo实现滚动条的滚动
    // 该方法回自动获取到点击的id
    tabsChangeFn (id) {
      this.$nextTick(() => {
        window.scrollTo(0, nameToTop[id] || 0)
      })
    }
  },
  // 优化：切换页面保留该页面为滚动位置,切换回来还能继续保留该位置
  // 里面组件路由-beforeRouteLeave-记录离开页面的时候，滚动条距离
  // 将滚动条距离保存到当前路由的元数据中meta
  // from代表当前路由页面
  beforeRouteLeave (to, from, next) {
    from.meta.top = window.scrollY// 获取滚动条距离
    next()// 必须写
  }
}
</script>

<style scoped lang="less">
.imgSize {
  width: 100px;
  height: 30px;
}
/deep/.van-tabs__content {
  padding-top: 44px;
}
.box {
  height: 700px;
  background-color: antiquewhite;
}
// 设置 tabs 容器的样式
/deep/ .van-tabs__wrap {
  padding-right: 30px;
  background-color: #fff;
}

// 设置小图标的样式
.moreChannels {
  position: fixed;
  top: 62px;
  right: 8px;
  z-index: 999;
}
/* 频道编辑弹出层铺满屏幕 */
.edit_wrap {
  width: 100%;
  height: 100%;
}
</style>
